﻿/*
Copyright (c) 2010 Lance Ward
This software is licensed under the MIT license, except where otherwise noted.
For complete license details, refer to license.txt
*/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ADNTimeline
{
	public partial class TimeRuler : Control
	{
		private int xOffset = 0;
		private int tickWidth = 12;
		private int labelFrequency = 5;
		private int startNumber = 0;
        private int selectedFrame = -1;

        public event EventHandler SelectionChange;

		public TimeRuler()
		{
			InitializeComponent();
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int XOffset
		{
			get { return xOffset; }
			set
			{
				xOffset = value;
				this.Invalidate();
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int TickWidth
		{
			get { return tickWidth; }
			set
			{
				tickWidth = value;
				this.Invalidate();
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int LabelFrequency
		{
			get { return labelFrequency; }
			set
			{
				labelFrequency = value;
				this.Invalidate();
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int StartNumber
		{
			get { return startNumber; }
			set
			{
				startNumber = value;
				this.Invalidate();
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int SelectedFrame
        {
            get { return selectedFrame; }
            set 
			{ 
				selectedFrame = value;
				this.Invalidate();
			}
        }

        private void OnSelectionChange()
        {
			if (SelectionChange != null) { SelectionChange(this, EventArgs.Empty); }
        }

		protected override void OnPaint(PaintEventArgs e)
		{
			DrawTicks(e.Graphics);
			DrawLabels(e.Graphics);
			DrawMarker(e.Graphics);
		}

		private void DrawTicks(Graphics g)
		{
			int x = xOffset;
			Point start = new Point(x, this.ClientRectangle.Bottom - 5);
			Point end = new Point(x, this.ClientRectangle.Bottom - 3);
			Pen p = new Pen(Color.DarkGray);

			while (x < this.ClientRectangle.Width)
			{
				x += tickWidth;
				start.X = x;
				end.X = x;
				g.DrawLine(p, start, end);
			}
		}

		private void DrawLabels(Graphics g)
		{
			//write text for every 5th number
			int x = xOffset;
			Brush b = new SolidBrush(Color.DarkGray);
			Font f = new Font("Arial", 7.0f);
			PointF labelAnchor = new PointF(x, this.ClientRectangle.Y + 3);
            int maxLabel = (this.ClientRectangle.Width / tickWidth) + startNumber;

			for(int i = startNumber + 5; i < maxLabel; i += 5)
			{
				x += tickWidth * 5;
				labelAnchor.X = x - (g.MeasureString(i.ToString(), f).Width / 2.0f);
				g.DrawString(i.ToString(), f, b, labelAnchor);
			}
		}

		private void DrawMarker(Graphics g)
		{
			//selected frame - frameoffset * tickwidth
			if (selectedFrame >= 0)
			{
				int frameX = ((selectedFrame - startNumber) * tickWidth) + xOffset;
				if (frameX >= xOffset)
				{
					Rectangle markerRect = new Rectangle(frameX, this.ClientRectangle.Top, tickWidth, this.ClientRectangle.Height);
					Brush b = new SolidBrush(Color.FromArgb(155, Color.Red));

					g.FillRectangle(b, markerRect);
				}
			}
		}


		protected override void OnMouseClick(MouseEventArgs e)
		{
			base.OnMouseClick(e);
			selectedFrame = GetClickedFrame(e.X, e.Y);
			this.Invalidate();
			OnSelectionChange();
		}

		private int GetClickedFrame(int x, int y)
		{
			float closestFrame = ((float)x - xOffset) / (float)tickWidth;
			closestFrame += startNumber;
			return (int)Math.Floor(closestFrame);
		}
	}
}
